/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { useEffect, useState } from 'react';
import { BreakpointManager } from './BreakpointManager';
import { BreakpointMap, BreakpointValueType, WidthBreakpoint } from '../config/breakpoints/types';
import { widthBreakpoints, widthBreakpointsMap } from '../config/breakpoints/breakpoints';

export function useBreakpointValue<T extends BreakpointMap<T>>(values: T, referenceWidth?: number): BreakpointValueType<T> {
  const breakpointManager = BreakpointManager.getInstance();
  const [currentWidthBreakpoint, setCurrentWidthBreakpoint] = useState<WidthBreakpoint>(breakpointManager.getCurrentWidthBreakpoint() as WidthBreakpoint);

  useEffect(() => {
    // 如果传入 referenceWidth，直接计算断点并返回
    if (referenceWidth !== undefined) {
      const calculatedBreakpoint = breakpointManager.calculateBreakpoint(referenceWidth, widthBreakpointsMap) as WidthBreakpoint;
      setCurrentWidthBreakpoint(calculatedBreakpoint);
      return (): void => {}; // 直接返回，不需要订阅
    }

    // 订阅断点变化
    const unsubscribe = breakpointManager.subscribeToBreakpoint(newWidthBreakpoint => {
      setCurrentWidthBreakpoint(newWidthBreakpoint as WidthBreakpoint);
    });

    // 清理订阅
    return (): void => {
      unsubscribe();
    };
  }, [referenceWidth]);

  // 根据当前横向断点选择值
  let result = values[currentWidthBreakpoint as keyof BreakpointMap<T>];

  // 如果当前断点值为 null 或 undefined，遍历返回上一级断点的值，直到匹配为止
  if (result === null || result === undefined) {
    widthBreakpoints.forEach((breakpoint, index) => {
      if (breakpoint === currentWidthBreakpoint) {
        // 从当前断点开始向上查找
        for (let i = index - 1; i >= 0; i--) {
          const previousBreakpoint = widthBreakpoints[i];
          const preValue = values[previousBreakpoint];
          if (preValue !== null && preValue !== undefined) {
            result = preValue;
            break;
          }
        }
      }
    });
  }

  // 如果还是没有，尝试 fallback 到 base
  return (result ?? values.base) as BreakpointValueType<T>;
}
